--Basic Tool Info
TOOL.Category			= "Constraints"
TOOL.Name				= "#tool.omnicon.name"
TOOL.Command		= nil
TOOL.ConfigName		= "( . )( . ) BEWBIES"

--Put our ConVars into a table
TOOL.ClientConVar =
{
	["area"]					=		"0",
	["areaamount"]			=		"256",
	["freeze"]					=		"1",
	["shadow"]				= 		"1",
	["nocollide"]				=		"1",
	["weld"]					= 		"1",
	["parent"]					=		"0",
--	["parentphys"]			= 		"0",
	["pnocollide"]				= 		"1",
	["autoconstraint"]		=		"0",
	["constraintremove"]	= 		"0",
	["parentremove"]		= 		"0",
	["removenocollide"]	=		"0",
--	["autonocollide"]		= 		"0",
--	["autoweld"]				= 		"0",
	["model"]					=		"models/cheeze/wires/cpu.mdl",
	["pweight"]				=		"1"
}

--Set up some tables for later
TOOL.TargEnts = {}
TOOL.TargSets = {}
TOOL.TargRenders = {}
TOOL.ModelList = {
	"models/cheeze/wires/cpu.mdl",
	"models/kobilica/capacatitor.mdl",
	"models/kobilica/lowpolygate.mdl",
	"models/kobilica/relay.mdl",
	"models/kobilica/transistor.mdl",
	"models/kobilica/transistorsmall.mdl",
	"models/kobilica/value.mdl"
}
TOOL.Filter = {
	--Borrowed from Wiremod's Expression 2 "Find" extension
	"info_apc_missile_hint", "info_camera_link", "info_constraint_anchor", "info_hint", "info_intermission", "info_ladder_dismount",
	"info_landmark", "info_lighting", "info_mass_center", "info_no_dynamic_shadow", "info_node", "info_node_air", "info_node_air_hint",
	"info_node_climb", "info_node_hint", "info_node_link", "info_node_link_controller", "info_npc_spawn_destination", "info_null",
	"info_overlay", "info_particle_system", "info_projecteddecal", "info_snipertarget", "info_target", "info_target_gunshipcrash",
	"info_teleport_destination", "info_teleporter_countdown", "info_player_allies", "info_player_axis", "info_player_combine",
	"info_player_counterterrorist", "info_player_deathmatch", "info_player_logo", "info_player_rebel", "info_player_start",
	"info_player_terrorist", "info_player_blu", "info_player_red", "prop_dynamic", "physgun_beam", "player_manager",
	"predicted_viewmodel", "gmod_ghost"
}

--Set up our CLIENT side stuff, Toolgun Text, Toolgun animation, etc etc.
if CLIENT then
	language.Add( "tool.omnicon.name", "OmNi Constraint 3.2 Beta" )
    language.Add( "tool.omnicon.desc", "For all your constraining needs." )
    language.Add( "tool.omnicon.0", "M1: Select Props (E+M1: Select All, Shift+M1: Constraintless Parent, Ctrl+M1: Chip Spawn).  M2: Perform actions on Target.  R: Clear Selected. (E+R: Clear only Parented Props)" )
	
	function TOOL.BuildCPanel(panel)
		panel:AddControl("Label",{Text = "!!!- Always dupe your stuff before parenting!! -!!!", Description = "", Help=true})
		panel:AddControl("Label", {Text = "General Options", Description = ""})
		--panel:AddControl("CheckBox", {Label = "Use Area Select Instead (Disabled, Nadmod keeps giving ownership to crap)", Command = "omnicon_area"})
		--panel:AddControl( "Slider", {Label = "Area", Type = "Float", 	Command = "omnicon_areaamount", 	Min = "1", 	Max = "2048"})
		panel:AddControl("CheckBox", {Label = "Freeze All Involved Objects", Command = "omnicon_freeze"})
		panel:AddControl("CheckBox", {Label = "Remove Shadows", Command = "omnicon_shadow"})
		panel:AddControl("Label", {Text = "Constraints", Description = "WELD THOSE MO F%$#$%#"})
		panel:AddControl("CheckBox", {Label = "Nocollide", Command = "omnicon_nocollide"})
		panel:AddControl("CheckBox", {Label = "Weld", Command = "omnicon_weld"})
		panel:AddControl("CheckBox", {Label = "Parent", Command = "omnicon_parent"})
		panel:AddControl("CheckBox", {Label = "Parent Nocollides (useful for constraintless parents)", Command = "omnicon_pnocollide"})
		panel:AddControl( "PropSelect", {Label = "Select Parent Model \n(crouch+mouse1 to manually spawn)", ConVar = "omnicon_model", Category = "Models", Height = 1, Models = list.Get( "omnicon_models" )})
		panel:AddControl( "Slider", {Label = "Chip Weight", Type = "Float", 	Command = "omnicon_pweight", 	Min = "1", 	Max = "50000"})
		panel:AddControl("Label", {Text = "Auto-Constraint (experimental, dupe first)", Description = ""})
		panel:AddControl("CheckBox", {Label = "Auto Constraint Mode", Command = "omnicon_autoconstraint"})
		panel:AddControl("Label", {Text = ""})
		panel:AddControl("Label", {Text = "Constraint Removal (disables conflicting settings)", Description = ""})
		panel:AddControl("CheckBox", {Label = "Remove All Constraints", Command = "omnicon_constraintremove"})
		panel:AddControl("CheckBox", {Label = "UnParent", Command = "omnicon_parentremove"})
		panel:AddControl("CheckBox", {Label = "Remove Nocollide All/Enable Collisions", Command = "omnicon_removenocollide"})
		panel:AddControl("Label",{Text = "Selection Color Key: \nBlue = Normal Select or Parenting with Constraints. \nGreen = Parenting WITHOUT constraints.  \nPurple and Red = Blue or Green that's already parented.", Description = ""})
		panel:AddControl("Label",{Text = "Quick Instructions:", Description = "", Help=true})
		panel:AddControl("Label",{Text = "Mouse1: Select Props (E Key+Mouse1: Select All, Shift+Mouse1: Constraintless Parent, CTRL+Mouse1: Manual Chip Spawn).  Mouse2: Perform actions on Target.  R Key: Clear Selected. (E Key+R Key: Clear only Parented Props)", Description = ""})
		panel:AddControl("Label",{Text = "", Description = ""})
		panel:AddControl("Label",{Text = "OmNi Constraint Video Tutorial wanted.  Want to make one?  Contact Mechanos", Description = "", Help=true})
	end
	
	for k, v in pairs(TOOL.ModelList) do
		list.Set("omnicon_models",v,{})
	end
	
	function TOOL:LeftClick(trace)
		return true
	end
	function TOOL:RightClick(trace)
		return true
	end
end

--SERVER Side, Everything Else
if SERVER then
	--Entity setup function to restore NoCollide Alls and ULX compatibility on paste
	local function SetGroup(_,Entity,Data)
		if not Data.Group then return false end
		Entity:SetCollisionGroup(Data.Group)
		if type(Entity.EntityMods) == "table" then
			if type(Entity.EntityMods.OmNi) == "table" then
				Entity.jailWall = true
			end
		end
		duplicator.StoreEntityModifier( Entity, "nocollideallomni" , Data)
	end
	duplicator.RegisterEntityModifier( "nocollideallomni", SetGroup )
	
	--Left Click, durr
	function TOOL:LeftClick(trace)
		if not trace.Hit then return end
		if not util.IsValidPhysicsObject(trace.Entity, trace.PhysicsBone) then return false end
	
		local ent = trace.Entity
		if not IsValid(ent) and not self:GetOwner():KeyDown(IN_DUCK) then return
		elseif ent:IsPlayer() then return
		elseif ent:IsWorld() and not self:GetOwner():KeyDown(IN_DUCK) then return false
		end
		
		local ply = self:GetOwner()
		
		local area 						= (self:GetClientNumber("area") == 1)
		local area 						= false		--Temporarily disabled 'till we can stop targetting bad stuff
		local areaamount				= math.Clamp( self:GetClientNumber("areaamount"), 1, 2024 )
		local pweight					= math.Clamp(self:GetClientNumber("pweight"),1,50000)

		--Function for adding colors to selected props based on their current status
		local function EntPainter(v, switch)
			--Check for Prop Protection
			if CPPI then
				if not v:CPPICanTool(ply,"constraint") then return end
			end
			
			local red = Color(255,0,0,200)
			local green = Color(0,255,0,200)
			local purple = Color(255,0,255,200)
			local blue = Color(0,0,255,200)
			
			local edex = v:EntIndex()
			if not self.TargEnts[edex] then
				local col = Color(0,0,0,0)
				col.r,col.g,col.b,col.a = v:GetColor()
				self.TargEnts[edex] = col
				self.TargSets[edex] = switch		--true = constraints, false = noconstraints
				self.TargRenders[edex] = v:GetRenderMode() 
				if switch == false then
					if IsValid(v:GetParent()) then v:SetColor(red) else v:SetColor(green) end
					v:SetRenderMode(4) 
				else
					if IsValid(v:GetParent()) then v:SetColor(purple) else v:SetColor(blue) end
					v:SetRenderMode(4) 
				end
			else
				if self.TargSets[edex] == true and switch == false then
					self.TargSets[edex] = false
					if IsValid(v:GetParent()) then v:SetColor(red) else v:SetColor(green) end
					v:SetRenderMode(4) 
				elseif self.TargSets[edex] == false and switch == true then
					self.TargSets[edex] = true
					if IsValid(v:GetParent()) then v:SetColor(purple) else v:SetColor(blue) end
					v:SetRenderMode(4) 
				else
					local col = self.TargEnts[edex]
					v:SetColor(col.r,col.g,col.b,col.a)
					v:SetRenderMode(self.TargRenders[edex]) 
					self.TargEnts[edex] = nil
					self.TargSets[edex] = nil
					self.TargRenders[edex] = nil
				end
			end
			return true
		end
		
		if self:GetOwner():KeyDown(IN_DUCK) then
			--Manually spawn a parent chip so they can place it where they want!
			local model = self:GetClientInfo("model")
			local ParentAMD = ents.Create("prop_physics")
			
			local AMDModel = model or "models/cheeze/wires/cpu.mdl"
			ParentAMD:SetModel(AMDModel)
			local hitnorm = trace.HitNormal
			local angle = hitnorm:Angle() + Angle(90,0,0)
			local getpos = trace.HitPos + hitnorm*1
			ParentAMD:SetPos(getpos)
			ParentAMD:SetAngles(angle)
			ParentAMD:Spawn()
			SetGroup(_,ParentAMD,{Group = COLLISION_GROUP_WORLD})
			ParentAMD.CollisionGroup = COLLISION_GROUP_WORLD
			ParentAMD:DrawShadow(false)
			local physAMD = ParentAMD:GetPhysicsObject()
			if physAMD:IsValid() then
				physAMD:EnableMotion(false)
				physAMD:Sleep()
				physAMD:SetMass(pweight)
			end
			local OmNi = {parent=true,manual=true}
			duplicator.StoreEntityModifier(ParentAMD,"OmNi",OmNi)
			ParentAMD.EntityMods = ParentAMD.EntityMods or {OmNi}
			local EntityMeta = FindMetaTable("Entity")	--Annoying prop protection check :/
			if type(EntityMeta.CPPISetOwner) == "function" then ParentAMD:CPPISetOwner(ply) end
			undo.Create("OmNi Chip ("..AMDModel..")")
			undo.AddEntity(ParentAMD)
			undo.SetPlayer(ply)
			undo.Finish()
		elseif self:GetOwner():KeyDown(IN_USE) then
			local speed = self:GetOwner():KeyDown(IN_SPEED)
			local found = {}
			if area then
				found = ents.FindInSphere(ent:GetPos(), areaamount)
				--print("Searching Sphere")
			else
				found = constraint.GetAllConstrainedEntities(ent)
				--print("Getting Constraints")
			end
			--Filter out stuff we don't want or bad things happen
			--for k,v in pairs(found) do
				--if table.HasValue(self.Filter,v:GetClass()) or v:IsWorld() then
					--found[k] = nil
				--end
			--end
			for k,v in pairs(found) do
				--if CPPI then
				--	local owned = v:CPPICanTool(ply, "constraint")
				--	print(owned)
				--else
				--	local owned = true
				--end
				--if owned then
					if not speed then
						EntPainter(v, true)
					else
						EntPainter(v, false)
					end
				--end
			end
			return
		elseif not self:GetOwner():KeyDown(IN_SPEED) then
			return EntPainter(ent, true)
		else
			return EntPainter(ent, false)
		end

		return true
	end
	
	function TOOL:RightClick(trace)
		if not trace.Hit then return end
		if not util.IsValidPhysicsObject(trace.Entity, trace.PhysicsBone) then return false end
	
		local ent = trace.Entity
		if not IsValid(ent) then return
		elseif ent:IsPlayer() then return
		elseif ent:IsWorld() then return false
		end
		
		local bone = trace.PhysicsBone
		local ephys = ent:GetPhysicsObject()
		local entcentermass = Vector(0,0,0)
		if ephys:IsValid() then
			entcentermass = ent:LocalToWorld(ephys:GetMassCenter())
		else
			entcentermass = ent:LocalToWorld(ent:OBBCenter())
		end
		local ply = self:GetOwner()
	
		local freeze 						= (self:GetClientNumber("freeze")					==	1)
		local nocollide 					= (self:GetClientNumber("nocollide")				==	1)
		local weld 						= (self:GetClientNumber("weld")						==	1)
		local parent 						= (self:GetClientNumber("parent")					==	1)
		local pnocollide 				= (self:GetClientNumber("pnocollide")				== 	1)
		local autoconstraint			= (self:GetClientNumber("autoconstraint")		==	1)
		local constraintremove		= (self:GetClientNumber("constraintremove")	==	1)
		local parentremove			= (self:GetClientNumber("parentremove")		==	1)
		local removenocollide		= (self:GetClientNumber("removenocollide")	==	1)
		local model						= self:GetClientInfo("model")
		local pweight 					= math.Clamp(self:GetClientNumber("pweight"),1,50000)
		
		----Because sometimes we just dun take kindly to yer kind 'round HURR----
		if constraintremove or parentremove then
			ply:ConCommand("omnicon_nocollide 0")
			ply:ConCommand("omnicon_weld 0")
			ply:ConCommand("omnicon_parent 0")
			ply:ConCommand("omnicon_autoconstraint 0")
			local nocollide = false
			local weld = false
			local parent = false
			local autoconstraint = false
		end
		
		----Freeze all involved parts----
		if freeze and ephys:IsMoveable() then
			ephys:EnableMotion(false)
			ephys:Wake()
		end
		
		----Search for our Parent Chip and if there are more than 1 for some reason, mark the rest for deletion
		local ParentAMD = nil
		local Extras = {}
		for k,v in pairs(self.TargEnts) do
			local prop = ents.GetByIndex(k)
			--Select existing chip and remove extras
			if parent or parentremove or constraintremove then
				if type(prop.EntityMods) == "table" then
					--print("EntityMods Found")
					if type(prop.EntityMods.OmNi) == "table" then
						--print("OmNi Found")
						if IsValid(ParentAMD) and (parentremove or constraintremove) then
							Extras[k] = prop
							print("OmNi Constraint: Extra Chip Marked for Removal")
						else
							ParentAMD = prop
							--SetGroup(_,ParentAMD,{Group = COLLISION_GROUP_WORLD})
						end
					end
				end
			end
		end
		
		----Crash Prevention
		for k,v in pairs(self.TargEnts) do
			local prop = ents.GetByIndex(k)
			if IsValid(prop) then
				--Abort if they're trying to parent something they shouldn't be
				if prop.is_plug then	--Check for hacky Resource Pump Plugs
					ply:PrintMessage( HUD_PRINTCENTER, "Environments Resource Pump plug detected.  Deactivate your resource pump and try again." )
					return false
				elseif IsValid(prop:GetParent()) and parent and not parentremove and not constraintremove then
					--print(tostring(k) .. " Parent Detected")
					ply:PrintMessage( HUD_PRINTCENTER, "Unparent before attempting to make new parents.  They're highlighted in red/purple." )
					--break
					return false
				elseif IsValid(ent:GetParent()) and parent then
					if ent:GetParent() == prop then
						ply:PrintMessage( HUD_PRINTCENTER, "Don't parent things to their children." )
						return false
					end
				end
			end
		end
		
		----Now we're clear to start constrainting
		local counter = 0	--autoconstraint counter
		for k,v in pairs(self.TargEnts) do
			local prop = ents.GetByIndex(k)
			if IsValid(prop) then
			
				--set ignore to true if our current prop is our target
				local ignore = false
				if prop == ent then ignore = true end
				
				--used to ignore seats, now it's not a problem
				local seat = false --prop:IsVehicle()
				
				local phys = prop:GetPhysicsObject()
				local pos = prop:GetPos()
				
				--Our prop has a physbox, continue
				if phys:IsValid() then
					--Check if we're removing parenting/constraints
					if (parentremove or constraintremove or (parent and not ignore)) and IsValid(prop:GetParent()) then
						prop:SetParent()
						prop:SetPos(pos)
						if removenocollide then
							SetGroup(_,prop,{Group = COLLISION_GROUP_NONE})
						end
						phys:Wake()
						phys:EnableCollisions(true)
						phys:EnableMotion(false)
						ignore = true
					end
					if constraintremove then
						constraint.RemoveAll(prop)
						ignore = true
					end
					
					--Freeze stuff and Remove Shadows
					if (freeze or parent) and phys:IsMoveable() then
						phys:EnableMotion(false)
						if not parent then phys:Wake() end
					end
					if shadow then prop:DrawShadow(false) else prop:DrawShadow(true) end
					
					--We aren't removing constraints and aren't targetting ourselves, continue
					if not ignore and not parentremove and not constraintremove then
					
						--First we add nocollides if we aren't welding, since welds can handle nocolliding
						if (nocollide and not weld) or (parent and self.TargSets[k] == false and pnocollide) then 
							constraint.NoCollide(prop,ent,0,0) 
						end
						
						
						--AUTOCONSTRAINT!!  WEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
						if (autoconstraint and self.TargSets[k] == true) then
							local maxs = prop:OBBMaxs()
							maxs = prop:LocalToWorld(maxs)
							local center = prop:OBBCenter()
							center = prop:LocalToWorld(center)
							local length = maxs:Distance(center)
							local targets = ents.FindInSphere(center, length)
							for kt,tgt in pairs(targets) do
								if IsValid(tgt) then
									local tgtedex = tgt:EntIndex()
									local color = self.TargEnts[tgtedex] or nil
									if tgt == prop then
										--print("Target was Prop")
									elseif type(color) == "table" then
										constraint.Weld(prop,tgt,0,0,0,true,false)
										counter = counter + 1
									else
										--print("Type was - "..type(color))
									end
								end
							end
							--PrintTable(self.TargEnts)
							ply:PrintMessage( HUD_PRINTCENTER, "Auto Constraint has added "..tostring(counter).." Constraints" )
						end
						
						--Now we do our normal Welding and Chip Spawning
						if parent or weld then
							if parent then
								if not IsValid(ParentAMD) then
									ParentAMD = ents.Create("prop_physics")
									local AMDModel = model or "models/cheeze/wires/cpu.mdl"
									ParentAMD:SetModel(AMDModel)
									ParentAMD:SetAngles(ent:GetAngles())
									ParentAMD:SetPos(Vector(0,0,0))
									ParentAMD:Spawn()
									
									local AMDcenter = ParentAMD:GetPos()
									local physAMD = ParentAMD:GetPhysicsObject()
									if physAMD:IsValid() then
										physAMD:EnableMotion(false)
										physAMD:Sleep()
										AMDcenter = ParentAMD:LocalToWorld(physAMD:GetMassCenter())
										physAMD:SetMass(pweight)
									end
									
									local AMDoffset = AMDcenter - ParentAMD:GetPos()
									ParentAMD:SetPos(entcentermass - AMDoffset)

									local OmNi = {parent=true,manual=false}
									duplicator.StoreEntityModifier(ParentAMD,"OmNi",OmNi)
									ParentAMD.EntityMods = ParentAMD.EntityMods or {OmNi}
								
									local EntityMeta = FindMetaTable("Entity")	--Annoying prop protection check :/
									if type(EntityMeta.CPPISetOwner) == "function" then
										ParentAMD:CPPISetOwner(ply)
									end
								
									constraint.Weld(ParentAMD,ent,0,bone,0,true,false)
									if self.TargSets[k] == true then
										if nocollide then
											constraint.Weld(prop,ParentAMD,0,0,0,true,false)
											constraint.Weld(prop,ent,0,bone,0,true,false)
										else
											constraint.Weld(prop,ParentAMD,0,0,0,false,false)
											constraint.Weld(prop,ent,0,bone,0,false,false)
										end
									elseif self.TargSets[k] == false then
										constraint.RemoveAll(prop)
										if pnocollide then timer.Simple( 1, function() constraint.NoCollide(prop,ent,0,0) end ) end
									end
								elseif IsValid(ParentAMD) and self.TargSets[k] == true then
									if nocollide then
										constraint.Weld(prop,ParentAMD,0,0,0,true,false)
										constraint.Weld(prop,ent,0,bone,0,true,false)
									else
										constraint.Weld(prop,ParentAMD,0,0,0,false,false)
										constraint.Weld(prop,ent,0,bone,0,false,false)
									end
								elseif IsValid(ParentAMD) and self.TargSets[k] == false then
									constraint.RemoveAll(prop)
									if pnocollide then timer.Simple( 1, function() constraint.NoCollide(prop,ent,0,0) end ) end
								end
							else
								if nocollide then constraint.Weld(prop,ent,0,bone,0,true,false) else constraint.Weld(prop,ent,0,bone,0,false,false) end
							end
						end
						
						--Now we parent our Chip to our true Parent
						if parent and not seat then
							if IsValid(ParentAMD) then
								phys:Sleep()
								if self.TargSets[k] == false then SetGroup(_,prop,{Group = COLLISION_GROUP_WORLD}) end
								prop:SetParent(ParentAMD)
								prop:SetSolid(SOLID_VPHYSICS)
							end
						end
					end
					
					--Almost done, set the prop's color back
					prop:SetColor(v.r,v.g,v.b,v.a)
					--self.TargEnts[k] = nil
					--self.TargSets[k] = nil
				end
			end
		end
		
		--Extra handling for Parent Chips
		if IsValid(ParentAMD) then
			--Apply settings to our Chip if we're keeping it
			if parent and not parentremove and not constraintremove then
				ParentAMD:SetParent(ent)
				ParentAMD:SetSolid(SOLID_VPHYSICS)
				
				SetGroup(_,ParentAMD,{Group = COLLISION_GROUP_WORLD})
				ParentAMD.CollisionGroup = COLLISION_GROUP_WORLD
				ParentAMD:SetColor(Color(255, 255, 255, 50))
				if ParentAMD.EntityMods then --For some reason it wasn't saving the color :/
					ParentAMD.EntityMods.colour = {
						Color = {
							a=50,
							b=255,
							g=255,
							r=255
						},
						RenderMode=0,
						RenderFX=0
					}
				end
				ParentAMD:DrawShadow(false)
			end
			
			--Unparenting?  Check if it's a manually spawned chip, if not, remove it
			if parentremove or constraintremove then
				if type(ParentAMD.EntityMods) == "table" then
					PrintTable(ParentAMD.EntityMods)
					if type(ParentAMD.EntityMods.OmNi) == "table" then
						if not ParentAMD.EntityMods.OmNi.manual then
							ParentAMD:Remove()
						end
					else
						ParentAMD:Remove()
					end
				else
					ParentAMD:Remove()
				end
			end
		end
		
		--Remove Chip Clones we don't need GIT OUTTA HURR FGT
		for k,v in pairs(Extras) do
			local prop = ents.GetByIndex(k)
			if IsValid(prop) then
				prop:Remove()
			end
		end
		
		--Lastly, remove the shadow from our last target ent if needed
		if shadow then ent:DrawShadow(false) else ent:DrawShadow(true) end
		
		--Empty the Tables
		Extras = {}
		self.TargEnts = {}
		self.TargSets = {}
		return true
	end
	
	function TOOL:Reload()
		if table.Count(self.TargEnts) < 1 then return end
	
		if self:GetOwner():KeyDown(IN_USE) then
			for k,v in pairs(self.TargEnts) do
				local prop = ents.GetByIndex(k)
				if (IsValid(prop)) then
					if (IsValid(prop:GetParent())) then
						prop:SetColor(v.r,v.g,v.b,v.a)
						self.TargEnts[k] = nil
						self.TargSets[k] = nil
						--print("Parent in table, removed and cleaned!")
					end
				end
			end
			return true
		end
	
		for k,v in pairs(self.TargEnts) do
			local prop = ents.GetByIndex(k)
			if IsValid(prop) then
				prop:SetColor(v.r,v.g,v.b,v.a)
				--self.TargEnts[k] = nil
				--self.TargSets[k] = nil
			end
		end
		self.TargEnts = {}
		self.TargSets = {}
		return true
	end
end
--------------------------------------------------------